#include "head.h"
// 选项操作
user_t test(user_t data)
{
    f_list *list = (f_list *)malloc(sizeof(f_list));
    flight_data_file_scanf(list);
    while (1)
    {
        system("clear");
        printf("\033[1;31;40m请选择你需要的操作\n");
        printf("\033[1;33;40m选项一 显 示 航 班\n");
        printf("选项二 查 询 航 班\n");
        printf("选项三 购       票\n");
        printf("选项四 退       票\n");
        printf("选项五 显示身份信息\n");
        printf("选项六 修 改 密 码\n");
        printf("选项七 退       出 \033[0m\n");
        int sum;
        scanf("%d", &sum);
        system("clear");
        switch (sum) // 根据上述意思，将输入的数字进行选择
        {
        case 1:
            find_link_list(list); // 显示所有航班信息
            break;
        case 2:
            Find_flight(list); // 查询航班信息
            break;
        case 3:
            data = buy_ticket(list, data); // 购票系统
            break;
        case 4:
            data = get_refund_for_ticket(list, data);
            break;
        case 5: // 输出data的值就是自己的身份信息
            printf("用户名:%s  密码:%s  信息等级:%d  余额:%d 航班信息%d\n", data.name, data.passwd, data.IDcard, data.value, data.ticket);
            for (int i = 0; i < data.ticket; i++) // 输出航班信息
            {
                printf("%-6d", data.order[i].id);
                printf("%-15s", data.order[i].flighttype);
                printf("%-10s", data.order[i].startcity);
                printf("%-10s", data.order[i].arrivecity);
                printf("%02d:%02d\t", data.order[i].starttime[0], data.order[i].starttime[1]);
                printf("%02d:%02d\t    ", data.order[i].arrivetime[0], data.order[i].arrivetime[1]);
                printf("%-10s\t", data.order[i].flytime);
                printf("%-6d", data.order[i].value);
                printf("%-8d", data.order[i].maxNUM);
                printf("%-8d  ", data.order[i].leftbuyersa);
                printf("%c\n", data.order[i].whetherfly);
            }
            sleep(5); // 延时五秒
            break;
        case 6:
            data = change_password(data); // 修改密码
            break;
        case 7:
            free_double_link_list(&list); // 写入文件，集中写入文件，减少内存消耗
            return data;                  // 退出
        }
    }
}

// 显示
void find_link_list(f_list *list)
{
    print_forward_double_link_list(list); // 输出航班信息
    jump_out_of();                        // 输入空格后进行下一步
}
// 查找
void Find_flight(f_list *list)
{
    printf("\033[1;33;40m1编号查询      2终点站查询 \033[0m \n");
    int find_num;
    scanf("%d", &find_num);
    system("clear");
    if (find_num == 1)
    {
        printf("\033[1;31;40m请输入要查找的航班编号:\033[0m ");
        int id;
        scanf("%d", &id); // 输入要查询的航班id
        printf(" ");
        find_double_node_pos(list, id); // 根据航班编号查找信息
    }
    else if (find_num == 2)
    {
        printf("\033[1;31;40m请输入要查找的目的地\033[0m");
        char name[128];
        scanf("%s", name);                 // 输入要查询的航班终点站
        find_double_node_name(list, name); // 根据目的地查找航班信息
    }
}
// 购票
user_t buy_ticket(f_list *list, user_t data)
{
    FILE *fp = fopen("/home/student/桌面/代码/08/project/data/flights.txt", "r"); // 打开文件,获取航班信息
    f_node *ptr = list->next;                                                     // 创建节点，指向航班头节点
    int len = 0;
    char ch;
    int num = 1;
    if (fp == NULL) // 判断文件是否打开成功
    {
        ERRLOG("文件读取打开失败");
    }
    while ((ch = fgetc(fp)) != EOF) // 或许文件获取行数
    {
        if (ch == '\n')
            len++;
    }
    fseek(fp, 0, SEEK_SET);                                 // 把文件光标位移到行首
    print_forward_double_link_list(list);                   // 显示航班数量
    printf("\033[1;31;40m请输入要购票的航班编号\033[0m\n"); // 根据航班编号订票
    int ID;
    int meney;
    scanf("%d", &ID);
    for (size_t i = 0; i < len; i++) // 因为只有len行，所以最多只允许len次，一次获取一行
    {
        if (ID == ptr->data.id) // 对航班进行判断，是否是该编号的飞机
        {
            switch (data.IDcard) // 判断信息等级，对进行购票优惠
            {
            case 0:
                meney = ptr->data.value;
                break;
            case 1:
                meney = ptr->data.value * SILVER_DISCOUNT;
                break;
            case 2:
                meney = ptr->data.value * GOLD_DISCOUNT;
                break;
            case 3:
                meney = ptr->data.value * PLATINUM_DISCOUNT;
                break;
            }
            printf("\033[1;33;40m余额%d       票价%d\033[0m\n", data.value, meney); // 显示打折后的票价和余额
            if (data.value >= meney)                                                // 判断余额是否大于或者等于优惠后的价格
            {                                                                       // 购票后把机票信息存放在用户的ticket中
                num = 0;
                data.order[data.ticket] = ptr->data;
                data.ticket += 1;
                data.value -= meney;          // 购票后扣除余额的钱
                ptr->data.leftbuyersa--;      // 购票后，航班票减一
                flight_data_file_print(list); // 把链表写入航班信息
                printf("\033[1;31;40m购票成功\033[0m\n");
                sleep(3);
                return data; // 提前返回
            }
            fflush(stdin);
            fflush(stdout);
            sleep(3);
            if (data.value < meney)
            {
                num = 0;
                printf("\033[1;32;40m余额不足\n"); // 如果余额小于票价则显余额不足
                printf("是否充值\033[0m\n");
                fflush(stdin);
                fflush(stdout);
                getchar();
                char ch;
                scanf("%c", &ch);
                system("clear");
                if (ch == 'y')
                {
                    data = top_up(data); // 跳转充值选项
                    printf("\033[1;34;40m充值成功\033[0m\n");
                    break;
                }
                return data;
            }
        }
        ptr = ptr->next; // 信息不匹配，判断下一个值
    }
    if (num)
        printf("\033[1;31;40m没有该编号的航班\033[0m\n"); // 如果没有那个航班信息则输出这个语句
    sleep(5);
    return data;
}
// 充值
user_t top_up(user_t data)
{
    printf("\033[1;31;40m请选择充值金额\033[0m\n");
    printf("\033[1;33;40m 选项一 100\n");
    printf(" 选项二 500\n");
    printf(" 选项三 1000\033[0m\n");
    int len;
    scanf("%d", &len);
    switch (len)
    {
    case 1:
        data.value += 100; // 用户余额加100
        data.card += 100;
        break;
    case 2:
        data.value += 500; // 用户余额加500
        data.card += 500;
        break;
    case 3:
        data.value += 1000; // 用户余额加1000
        data.card += 1000;
        break;
    }
    return data;
}
// 退票
user_t get_refund_for_ticket(f_list *list, user_t data)
{
    f_node *ptr = list->next; // 创建ptr节点，让他移动到list的下一节点
    int get_meney;
    while (1)
    {
        if (data.ticket == ptr->data.id) // 判断自己的票信息是否有那个航班
        {
            ptr->data.whetherfly++; // 退票后，航班作为加一
            switch (data.IDcard)    // 判断信息等级，对进行购票优惠
            {
            case 0:
                get_meney = ptr->data.value;
                break;
            case 1:
                get_meney = ptr->data.value * SILVER_DISCOUNT;
                break;
            case 2:
                get_meney = ptr->data.value * GOLD_DISCOUNT;
                break;
            case 3:
                get_meney = ptr->data.value * PLATINUM_DISCOUNT;
                break;
            }
            data.value += get_meney; // 退费，余额加
            if (data.ticket == 1)
                data.ticket--;
            else
            {
                printf("请输入要退票的航班编号");
                int ID;
                scanf("%d", &ID);
                for (int i = 0; i < data.ticket; i++)
                {
                    if (ID == data.order[i].id)
                    {
                        data.ticket--;
                        data.order[i] = data.order[data.ticket];
                        break;
                    }
                }
            }
            flight_data_file_print(list); // 写入航班文件
            printf("\033[1;34;40m以成功退票\033[0m\n");
            sleep(3); // 延时
            return data;
        }
        ptr = ptr->next; // ptr指向自己的下一个节点
    }
    return data;
}
// 修改密码
user_t change_password(user_t data)
{
    while (1)
    {
        printf("\033[1;31;40m请输入原密码\033[0m\n");
        char password[3][128];                     // 用来接收密码
        scanf("%s", password[0]);                  // 存放原密码
        if (strcmp(password[0], data.passwd) == 0) // 判断密码是否正确
            while (1)
            {
                printf("\033[1;31;40m请输入新密码 \033[0m");
                scanf("%s", password[1]); // 输入新密码
                printf("\033[1;31;40m请再次输入新密码 \033[0m");
                scanf("%s", password[2]);                  // 再次输入
                if (strcmp(password[1], password[2]) == 0) // 判断两次密码是否相等
                {
                    strcpy(data.passwd, password[2]); // 把新密码复制过去
                    printf("\033[1;34;40m密码修改完成\033[0m\n");
                    sleep(3); // 延时
                    return data;
                }
            }
        else
        {
            printf("\033[1;34;40m原密码不正确\033[0m");
        }
    }
}
// 接收回车后执行下一步
void jump_out_of() 
{
    char ch = getchar();
    while (1)
    {
        if (ch == '\n')
            break;
    }
}
// 编号查找
void find_double_node_pos(f_list *list, int id)
{
    FILE *fp = fopen(FLIGHTS_FILE, "r"); // 以只读方式打开文件
    f_node *ptr = list->next;            // 创建节点指向链表头节点的下一个节点
    int len = 0;
    char ch;
    if (fp == NULL) // 判NULL
    {
        ERRLOG("文件读取打开失败");
        return;
    }
    while ((ch = fgetc(fp)) != EOF) // 获取行数
    {
        if (ch == '\n')
            len++;
    }
    fseek(fp, 0, SEEK_SET);
    for (size_t i = 0; i < len; i++)
    {
        if (id == ptr->data.id) // 判断航班id是否和输入的id相等
        {
            printf("班次\t机型\t\t起点站\t终点站\t起飞时间\t到达时间\t飞行时间\t票价\t载客量\t剩余座位\t是否飞\n");
            printf("%-8d", ptr->data.id);                                            // 航班班次
            printf("%-16s", ptr->data.flighttype);                                   // 飞机机型
            printf("%-12s", ptr->data.startcity);                                    // 航班起点站
            printf("%-12s", ptr->data.arrivecity);                                   // 航班终点站
            printf("%02d:%02d\t", ptr->data.starttime[0], ptr->data.starttime[1]);   // 起飞时间
            printf("%02d:%02d\t", ptr->data.arrivetime[0], ptr->data.arrivetime[1]); // 到达时间
            printf("%-10s", ptr->data.flytime);                                      // 飞行时间
            printf("%-8d", ptr->data.value);                                         // 票价
            printf("%-8d", ptr->data.maxNUM);                                        // 额定载客量
            printf("%-10d", ptr->data.leftbuyersa);                                  // 剩余座位数量
            printf("%c\n", ptr->data.whetherfly);
            sleep(5);
            return;
        }
        ptr = ptr->next; // ptr指向自己的下一个节点
    }
    printf("没有该编号的航班\n");
    sleep(5);
}
// 终点站查找
void find_double_node_name(f_list *list, char *name)
{
    FILE *fp = fopen(FLIGHTS_FILE, "r"); // 以只读方式打开
    f_node *ptr = list->next;            // ptr移动到头节点下一个指针
    int len = 0;
    char ch;
    int num = 0;
    if (fp == NULL) // 判NULL
    {
        ERRLOG("文件读取打开失败");
        return;
    }
    while ((ch = fgetc(fp)) != EOF) // 判行
    {
        if (ch == '\n')
            len++;
    }
    fseek(fp, 0, SEEK_SET); // 光标移动到行首
    for (size_t i = 0; i < len; i++)
    {
        if (!strcmp(ptr->data.arrivecity, name)) // 判断输入的终点站地址和航班的是否相同
        {                                        // 输出航班信息
            printf("班次\t机型\t\t起点站\t终点站\t起飞时间\t到达时间\t飞行时间\t票价\t载客量\t剩余座位\t是否飞\n");
            printf("%-8d", ptr->data.id);                                            // 航班班次
            printf("%-16s", ptr->data.flighttype);                                   // 飞机机型
            printf("%-12s", ptr->data.startcity);                                    // 航班起点站
            printf("%-12s", ptr->data.arrivecity);                                   // 航班终点站
            printf("%02d:%02d\t", ptr->data.starttime[0], ptr->data.starttime[1]);   // 起飞时间
            printf("%02d:%02d\t", ptr->data.arrivetime[0], ptr->data.arrivetime[1]); // 到达时间
            printf("%-10s", ptr->data.flytime);                                      // 飞行时间
            printf("%-8d", ptr->data.value);                                         // 票价
            printf("%-8d", ptr->data.maxNUM);                                        // 额定载客量
            printf("%-10d", ptr->data.leftbuyersa);                                  // 剩余座位数量
            printf("%c\n", ptr->data.whetherfly);
            num++;
        }
        ptr = ptr->next;
    }
    if (!num)
        printf("没有该编号的航班\n"); // 判断如果num为0就代表没有找到相对应的值
    sleep(5);
}
